package com.topone.service.impl;

import com.lly835.bestpay.enums.BestPayTypeEnum;
import com.lly835.bestpay.model.PayRequest;
import com.lly835.bestpay.model.PayResponse;
import com.lly835.bestpay.model.RefundRequest;
import com.lly835.bestpay.model.RefundResponse;
import com.lly835.bestpay.service.impl.BestPayServiceImpl;
import com.topone.Const.Model;
import com.topone.Enum.OrderStatusEnum;
import com.topone.Enum.PayStatusEnum;
import com.topone.Enum.TcUserCouponEnum;
import com.topone.Utils.JsonUtil;
import com.topone.Utils.MathUtil;
import com.topone.Utils.ServiceUtils;
import com.topone.dataObject.OrderMaster;
import com.topone.dataObject.PayNotification;
import com.topone.dataObject.TcUserCoupon;
import com.topone.dto.OrderDTO;
import com.topone.dto.TcUserCouponDTO;
import com.topone.repository.OrderMasterRepository;
import com.topone.repository.TcUserCouponRepository;
import com.topone.service.NotificationService;
import com.topone.service.OrderService;
import com.topone.service.PayService;
import com.topone.service.TcUserCouponService;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.pay.result.WxPayOrderNotifyResult;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Objects;

/**
 * Created by Administrator on 2018/2/2,0002.
 */
@Service
@Slf4j
public class PayServiceImpl implements PayService {
    @Autowired
    private BestPayServiceImpl bestPayService;
    @Autowired
    private OrderService orderService;
    @Autowired
    private WxMpService wxService;
    @Autowired
    private NotificationService notificationService;
    @Autowired
    private TcUserCouponService tcUserCouponService;
    @Autowired
    private OrderMasterRepository orderMasterRepository;
    @Autowired
    private TcUserCouponRepository tcUserCouponRepository;

    private static final String ORDER_NAME = "购买优惠券";

    @Override
    public PayResponse create(OrderDTO orderDTO) {
        PayRequest payRequest = new PayRequest();
        payRequest.setOrderId(orderDTO.getOrderId());
        payRequest.setOrderAmount(orderDTO.getOrderAmount().doubleValue());
        payRequest.setOpenid(orderDTO.getBuyerOpenid());
        payRequest.setOrderName(ORDER_NAME);
        payRequest.setPayTypeEnum(BestPayTypeEnum.WXPAY_H5); //支付方式
        log.info("【微信支付】payRequest={}", JsonUtil.toJson(payRequest));
        PayResponse payResponse = bestPayService.pay(payRequest);
        log.info("【微信支付】payResponse={}", JsonUtil.toJson(payResponse));

        return payResponse;
    }

    @Override
    public void notify(String notifyData) {
        //1.验证签名
        //2.支付的状态
        //3.支付的金额
        //4.支付人（下单人==支付人）
        log.info("【微信支付】异步通知,payRequest={}", JsonUtil.toJson(notifyData));
        PayNotification data = new PayNotification();
        try {
            WxPayOrderNotifyResult notifyResultData = wxService
                    .getPayService().getOrderNotifyResult(notifyData);
            BeanUtils.copyProperties(notifyResultData, data);
            log.info("resultNotification-->{}", data);
            data = notificationService.savePayResult(data);
        } catch (Exception e) {
            log.error("数据库更新支付结果失败");
        }

        //修改订单的支付状态
        log.info("---------data---------{}", ServiceUtils.toJson(data));
        if (!StringUtils.equals(data.getType(), Model.PAY_TYPE_SCAN)) {
            OrderDTO orderDTO = null;
            if (StringUtils.equals(data.getType(), Model.PAY_TYPE_BUY)) {
                orderDTO = orderService.findOne(data.getOrderId());
            } else if (StringUtils.equals(data.getType(), Model.Pay_TYPE_ONLY)) {
                orderDTO = orderService.findOrderMaster(data.getOrderId());
            }

            //查询订单是否存在
            if (Objects.isNull(orderDTO)) {
                log.error("【微信支付】异步通知,订单不存在 orderID＝{}", data.getOrderId());
            }
            //判断金额是否一致

            if (!MathUtil.equal(MathUtil.Fen2Yuan(data.getTotalFee()), orderDTO.getOrderAmount().doubleValue())) {
                log.error("【微信支付】异步通知,订单金额不一致 orderID＝{},微信通知金额＝{},系统定额＝{}"
                        , data.getOrderId(), data.getTotalFee(), orderDTO.getOrderAmount());
            }
            orderService.paid(orderDTO);
        } else if (StringUtils.equals(data.getType(), Model.PAY_TYPE_SCAN)) {
            OrderDTO order = orderService.findOrderMaster(data.getOrderId());
            log.info("========order========={}",order);
            TcUserCouponDTO tcUserCoupon = tcUserCouponService.findByCouponCode(data.getCouponCode());
            log.info("-----tcUserCoupon-------{}", ServiceUtils.toJson(tcUserCoupon));
            if (Objects.nonNull(tcUserCoupon)
                    && tcUserCoupon.getUseStatus() == TcUserCouponEnum.UNUSE.getCode()) {
                tcUserCoupon.setUseStatus(TcUserCouponEnum.USED.getCode());
                TcUserCoupon tcUserCoupon1=new TcUserCoupon();
                BeanUtils.copyProperties(tcUserCoupon,tcUserCoupon1);
                tcUserCouponRepository.save(tcUserCoupon1);
                log.info("------tcUserCoupon1------{}",tcUserCoupon1);
                order.setPayStatus(PayStatusEnum.SUCCESS.getCode());
                order.setOrderStatus(OrderStatusEnum.FINISH.getCode());
                OrderMaster orderMaster=new OrderMaster();
                BeanUtils.copyProperties(order,orderMaster);
                log.info("-----orderMaster----{}",orderMaster);
                orderMasterRepository.save(orderMaster);
            } else {
                log.error("无待使用优惠券");
            }
        } else {
            log.error("该用户没有待使用优惠券");
        }
    }

    /**
     * @param orderDTO
     * @return
     */
    @Override
    public RefundResponse refund(OrderDTO orderDTO) {
        RefundRequest refundRequest = new RefundRequest();
        refundRequest.setOrderId(orderDTO.getOrderId());
        refundRequest.setOrderAmount(orderDTO.getOrderAmount().doubleValue());
        refundRequest.setPayTypeEnum(BestPayTypeEnum.WXPAY_H5);
        log.info("【微信退款】request={}", JsonUtil.toJson(refundRequest));
        RefundResponse refundResponse = bestPayService.refund(refundRequest);
        log.info("【微信退款】refundResponse={}", JsonUtil.toJson(refundResponse));

        return refundResponse;
    }


}


